package clean

import (
	"context"

	"gitee.com/youkelike/ziam/zorm/store/mysql"
	"gitee.com/youkelike/ziam/zwatcher/options"
	"gitee.com/youkelike/ziam/zwatcher/watcher"
	"gitee.com/youkelike/zlog"
	"github.com/go-redsync/redsync/v4"
)

type cleanWatcher struct {
	ctx            context.Context
	mutex          *redsync.Mutex
	maxReserveDays int
}

func (cw *cleanWatcher) Run() {
	if err := cw.mutex.Lock(); err != nil {
		zlog.L(cw.ctx).Infow("cleanwatcher already run.")
		return
	}

	defer func() {
		if _, err := cw.mutex.Unlock(); err != nil {
			zlog.L(cw.ctx).Errorf("could not release cleanwatcher lock. err: %v", err)
			return
		}
	}()

	db, _ := mysql.GetMysqlFactoryOr(nil)

	rowsAffected, err := db.PolicyAudits().ClearOutdated(cw.ctx, cw.maxReserveDays)
	if err != nil {
		zlog.L(cw.ctx).Errorw("clean data from policy_audit failed", "error", err)
		return
	}

	zlog.L(cw.ctx).Debugf("clean data from policy_audit succ, %d rows affected", rowsAffected)
}

func (cw *cleanWatcher) Spec() string {
	return "@every 1d"
}

func (cw *cleanWatcher) Init(ctx context.Context, rs *redsync.Mutex, config interface{}) error {
	cfg, ok := config.(*options.WatcherOptions)
	if !ok {
		return watcher.ErrConfigUnavailable
	}

	*cw = cleanWatcher{
		ctx:            ctx,
		mutex:          rs,
		maxReserveDays: cfg.Clean.MaxReserveDays,
	}

	return nil
}

func init() {
	watcher.Register("clean", &cleanWatcher{})
}
